package com.ideaction.game.config.mongo;

import com.ideaction.game.utils.StringUtils;
import com.mongodb.MongoClientSettings;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import com.mongodb.client.MongoClient;
import com.mongodb.client.MongoClients;
import com.mongodb.connection.ConnectionPoolSettings;

import java.util.ArrayList;
import java.util.List;

import org.springframework.data.mongodb.MongoDatabaseFactory;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.SimpleMongoClientDatabaseFactory;

/**
 * 
 * @author ZGame
 *
 */
public abstract class MongoDBAbstractFactory {

	public MongoDatabaseFactory mongoDbFactory(MongoConfigProperties mongoConfigProperties) throws Exception {
		List<ServerAddress> serverAddressList = new ArrayList<>();
		String[] replicaSet = mongoConfigProperties.getReplicaSet().split(",");

		for (String s : replicaSet) {
			String host = s.substring(0, s.lastIndexOf(":"));
			String port = s.substring(s.lastIndexOf(":") + 1);
			serverAddressList.add(new ServerAddress(host, Integer.parseInt(port)));
		}
		// 连接认证，如果设置了用户名和密码的话
		MongoClientSettings settings = null;
		if (StringUtils.isNotBlank(mongoConfigProperties.getUserName())) {
			MongoCredential credential = MongoCredential.createScramSha1Credential(mongoConfigProperties.getUserName(),
					mongoConfigProperties.getAuthDB(), mongoConfigProperties.getPassword().toCharArray());
			settings = MongoClientSettings.builder().credential(credential)
					.applyToConnectionPoolSettings(builder -> builder.applySettings(getConnectionPoolSettings()))
					.applyToClusterSettings(builder -> builder.hosts(serverAddressList)).build();
		} else {
			settings = MongoClientSettings.builder()
					.applyToConnectionPoolSettings(builder -> builder.applySettings(getConnectionPoolSettings()))
					.applyToClusterSettings(builder -> builder.hosts(serverAddressList)).build();
		}

		MongoClient mongoClient = MongoClients.create(settings);
		// 创建MongoDbFactory
		SimpleMongoClientDatabaseFactory factory = new SimpleMongoClientDatabaseFactory(mongoClient,
				mongoConfigProperties.getDatabase());
		return factory;
	}

	abstract public MongoTemplate getMongoTemplate() throws Exception;
	abstract public ConnectionPoolSettings getConnectionPoolSettings();
}
